package plugin

import (
	"context"
	"fmt"
	"reflect"
)

func WithMutiValue(parent context.Context, kv ...interface{}) context.Context {
	if len(kv)%2 != 0 {
		panic("kv长度必须是偶数.")
	}
	mvc := mutiValueCtx{
		kvs: make(map[interface{}]interface{}),
	}
	mvc.Context = parent
	for i := 0; i < len(kv); i = i + 2 {
		mvc.kvs[kv[i]] = kv[i+1]
	}

	return &mvc
}

type mutiValueCtx struct {
	context.Context
	kvs map[interface{}]interface{}
}
type stringer interface {
	String() string
}

func (c *mutiValueCtx) String() string {
	var name string
	if s, ok := interface{}(c).(stringer); ok {
		name = s.String()
	}
	name = reflect.TypeOf(c).String()

	return fmt.Sprintf("%s.WithValue:[%v]", name, c.kvs)
}

func (c *mutiValueCtx) Value(key interface{}) interface{} {
	if v, ok := c.kvs[key]; ok {
		return v
	}
	return c.Context.Value(key)
}
